package controllers

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"

	"dcarpai-guider/internal/models"
	"dcarpai-guider/internal/services"
)

// ConfigController 配置控制器
type ConfigController struct {
	configService *services.ConfigService
	logger        *zap.Logger
}

// NewConfigController 创建新的配置控制器
func NewConfigController(configService *services.ConfigService, logger *zap.Logger) *ConfigController {
	return &ConfigController{
		configService: configService,
		logger:        logger,
	}
}

// GetAllConfigs 获取所有配置文件列表
// @Summary 获取配置列表
// @Description 获取系统中所有配置文件的列表
// @Tags 配置
// @Produce json
// @Security BearerAuth
// @Success 200 {array} models.ConfigListItem
// @Failure 401 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /configs [get]
func (cc *ConfigController) GetAllConfigs(c *gin.Context) {
	configs, err := cc.configService.GetAllConfigs()
	if err != nil {
		cc.logger.Error("获取配置列表失败", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "获取配置列表失败",
			"error":   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "获取配置列表成功",
		"data":    configs,
	})
}

// GetConfig 获取指定配置
// @Summary 获取配置详情
// @Description 根据配置名称获取配置的详细内容
// @Tags 配置
// @Produce json
// @Security BearerAuth
// @Param name path string true "配置名称"
// @Success 200 {object} models.Config
// @Failure 400 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /configs/{name} [get]
func (cc *ConfigController) GetConfig(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置名称不能为空",
		})
		return
	}

	config, err := cc.configService.GetConfig(name)
	if err != nil {
		cc.logger.Warn("获取配置失败", zap.String("name", name), zap.Error(err))
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "获取配置成功",
		"data":    config,
	})
}

// UpdateConfig 更新配置
// @Summary 更新配置
// @Description 更新指定名称的配置文件内容
// @Tags 配置
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param name path string true "配置名称"
// @Param config body models.ConfigRequest true "配置内容"
// @Success 200 {object} models.Config
// @Failure 400 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /configs/{name} [put]
func (cc *ConfigController) UpdateConfig(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置名称不能为空",
		})
		return
	}

	var req models.ConfigRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		cc.logger.Warn("更新配置请求参数错误", zap.Error(err))
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	// 确保请求中的名称与路径参数一致
	req.Name = name

	// 验证配置格式
	if err := cc.configService.ValidateConfig(name, req.Content); err != nil {
		cc.logger.Warn("配置格式验证失败",
			zap.String("name", name),
			zap.Error(err),
		)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置格式验证失败",
			"error":   err.Error(),
		})
		return
	}

	// 备份原配置
	if err := cc.configService.BackupConfig(name); err != nil {
		cc.logger.Warn("备份配置失败",
			zap.String("name", name),
			zap.Error(err),
		)
		// 备份失败不阻止更新，只记录警告
	}

	config, err := cc.configService.UpdateConfig(&req)
	if err != nil {
		cc.logger.Error("更新配置失败",
			zap.String("name", name),
			zap.Error(err),
		)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "更新配置失败",
			"error":   err.Error(),
		})
		return
	}

	cc.logger.Info("更新配置成功", zap.String("name", name))

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "更新配置成功",
		"data":    config,
	})
}

// CreateConfig 创建新配置
// @Summary 创建配置
// @Description 创建一个新的配置文件
// @Tags 配置
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param config body models.ConfigRequest true "配置信息"
// @Success 201 {object} models.Config
// @Failure 400 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /configs [post]
func (cc *ConfigController) CreateConfig(c *gin.Context) {
	var req models.ConfigRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		cc.logger.Warn("创建配置请求参数错误", zap.Error(err))
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	// 基本验证
	if req.Name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置名称不能为空",
		})
		return
	}

	if req.Content == nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置内容不能为空",
		})
		return
	}

	// 验证配置格式
	if err := cc.configService.ValidateConfig(req.Name, req.Content); err != nil {
		cc.logger.Warn("配置格式验证失败",
			zap.String("name", req.Name),
			zap.Error(err),
		)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置格式验证失败",
			"error":   err.Error(),
		})
		return
	}

	config, err := cc.configService.CreateConfig(&req)
	if err != nil {
		cc.logger.Error("创建配置失败",
			zap.String("name", req.Name),
			zap.Error(err),
		)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "创建配置失败",
			"error":   err.Error(),
		})
		return
	}

	cc.logger.Info("创建配置成功", zap.String("name", req.Name))

	c.JSON(http.StatusCreated, gin.H{
		"code":    201,
		"message": "创建配置成功",
		"data":    config,
	})
}

// DeleteConfig 删除配置
// @Summary 删除配置
// @Description 删除指定名称的配置文件
// @Tags 配置
// @Produce json
// @Security BearerAuth
// @Param name path string true "配置名称"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]interface{}
// @Failure 403 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /configs/{name} [delete]
func (cc *ConfigController) DeleteConfig(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置名称不能为空",
		})
		return
	}

	if err := cc.configService.DeleteConfig(name); err != nil {
		cc.logger.Error("删除配置失败", zap.String("name", name), zap.Error(err))

		// 根据错误类型返回不同的状态码
		if err.Error() == "不能删除系统关键配置文件" {
			c.JSON(http.StatusForbidden, gin.H{
				"code":    403,
				"message": err.Error(),
			})
		} else if err.Error() == "配置文件不存在" {
			c.JSON(http.StatusNotFound, gin.H{
				"code":    404,
				"message": err.Error(),
			})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code":    500,
				"message": err.Error(),
			})
		}
		return
	}

	cc.logger.Info("删除配置成功", zap.String("name", name))

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "删除配置成功",
	})
}

// BackupConfig 备份配置
// @Summary 备份配置
// @Description 创建指定配置文件的备份
// @Tags 配置
// @Produce json
// @Security BearerAuth
// @Param name path string true "配置名称"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /configs/{name}/backup [post]
func (cc *ConfigController) BackupConfig(c *gin.Context) {
	name := c.Param("name")
	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "配置名称不能为空",
		})
		return
	}

	if err := cc.configService.BackupConfig(name); err != nil {
		cc.logger.Error("备份配置失败", zap.String("name", name), zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "备份配置失败",
			"error":   err.Error(),
		})
		return
	}

	cc.logger.Info("备份配置成功", zap.String("name", name))

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "备份配置成功",
	})
}
